#!/bin/sh

usage() {
  echo "CernVM-FS catalog decryption"
  echo "Usage: cvmfs_decrypt [-d(ecompress)] -k <keyfile> -o <output file> <catalog directory>"
  echo "(key files are created with cvmfs_mkkey)"
  echo
}

IV=
KEY=
KEYID=

parse_keyfile() {
  local keyfile=$1
  
  if [ ! -f $keyfile ]; then
    echo "Key file not found"
    usage
    exit 1
  fi

  # Check for valid keyfile
  NUMBYTES=`cat $keyfile | wc -c`
  if [ $NUMBYTES -ne 64 ]; then
    echo "Invalid key file (length)"
    exit 1
  fi
  KEYID=`cat $keyfile | openssl sha1`
  if [ $KEYID != `basename $KEYFILE` ]; then
    echo "Invalid key file (name)"
    exit 1
  fi
  
  KEY=`cat $keyfile`
}


decrypt() {
  local chksum=$1
  local catalog=$2
  local outfile=$3
   
  head -1 "$chksum" | grep "[a-z0-9]\{40\}E[a-z0-9]\{72\}" > /dev/null
  if [ $? -ne 0 ]; then
    echo "Catalog is not encrypted"
    return 1
  fi

  LISTED_KEY=`head -1 $CHKSUM | tail -c72 | head -c40`
  if [ $LISTED_KEY != $KEYID ]; then
    echo "Key file does not match catalog (required: $LISTED_KEY)"
    return 1
  fi
  
  IV=`head -1 $CHKSUM | tail -c32`
  
  openssl enc -iv $IV -K $KEY -aes-256-cbc -in $catalog -d -out $outfile
  
  if [ $? -ne 0 ]; then
    echo "Decryption failed"
    return 1
  fi
  
  return 0
}


KEYFILE=
DECOMPRESS=0
OUTFILE=
while getopts "dk:o:" OPTION
do
  case $OPTION in
    d)
      DECOMPRESS=1
    ;;
    k)
      KEYFILE=$OPTARG
    ;;
    o)
      OUTFILE=$OPTARG
    ;;  
    ?)
      echo "Invalid option"
      exit 1
    ;;
  esac
done
shift $((OPTIND-1))
CLGDIR=$1

for reqvar in KEYFILE CLGDIR OUTFILE
do
   eval value=\$$reqvar
   if [ -z "$value" ]; then
      usage
      exit 1
   fi
done

parse_keyfile $KEYFILE
  
# Check catalog directory
if [ ! -f $CLGDIR/.cvmfscatalog ]; then
  echo "$CLGDIR/.cvmfscatalog not found"
  usage
  exit 1
fi

if [ ! -f $CLGDIR/.cvmfschecksum ]; then
  echo "$CLGDIR/.cvmfschecksum not found"
  usage
  exit 1
fi

CHKSUM="$CLGDIR/.cvmfschecksum"
CLG="$CLGDIR/.cvmfscatalog"

if [ $DECOMPRESS -eq 1 ]; then
  cvmfs_zpipe -d < "$CLGDIR/.cvmfschecksum" > "$CLGDIR/.cvmfschecksum.uncompressed"
  if [ $? -ne 0 ]; then
    echo "$CLGDIR/.cvmfschecksum invalid"
    rm -f "$CLGDIR/.cvmfschecksum.uncompressed"
    exit 1
  fi

  cvmfs_zpipe -d < "$CLGDIR/.cvmfscatalog" > "$CLGDIR/.cvmfscatalog.uncompressed"
  if [ $? -ne 0 ]; then
    echo "$CLGDIR/.cvmfscatalog invalid"
    rm -f "$CLGDIR/.cvmfschecksum.uncompressed" "$CLGDIR/.cvmfscatalog.uncompressed"
    exit 1
  fi
  
  CHKSUM="$CLGDIR/.cvmfschecksum.uncompressed"
  CLG="$CLGDIR/.cvmfscatalog.uncompressed"
fi

decrypt $CHKSUM $CLG $OUTFILE

if [ $DECOMPRESS -eq 1 ]; then
  rm -f "$CLG" "$CHKSUM"
fi

